#include "POW.h"

POW_T* POW_t;



//************************************
// Method:    	CALCU_SAMA					//< SAMA运算函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	bool						//< 成功：true；失败：false
// Parameter: 	Model_Base_t * arg			//< 模块参数结构体指针
// Parameter: 	float dt					//< 运算周期
// Parameter: 	bool * DI					//< 数字量输入值数组指针
// Parameter: 	bool * DO					//< 数字量输出值数组指针
// Parameter: 	bool * AI					//< 模拟量输入值数组指针
// Parameter: 	bool * AO					//< 模拟量输出值数组指针
//************************************
bool CALCU_SAMA(POW)(Model_Base_t* arg, float dt, bool* DI, bool* DO, float* AI, float* AO)
{
#define PERMIT_ERROR	0.0001			//< 浮点数在转化为整数时允许的精度误差
	/****************变量定义区开始**************/
	/*<<<<<定义输入变量>>>>>*/
	float bottom_value;				//< 底数
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<定义输出变量>>>>>*/
	float Output_Value = 0;			//< 输出值
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<定义参数变量>>>>>*/
	float index;					//< 指数
	float bias;						//< 偏置
	float k;						//< 系数
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/****************变量定义区结束**************/

	NAME(POW)* Obj = (NAME(POW)*)arg;

	/****************变量赋值**************/
	/*<<<<<输入变量赋值>>>>>*/
	bottom_value = AI[0];
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/*<<<<<参数变量赋值>>>>>*/
	index = Obj->Par.index;
	bias = Obj->Par.bias;
	k = Obj->Par.k;
	/*<<<<<<<<<<<<<<<<<<<<<<*/

	/**************变量赋值结束************/

	/********************************************/
	/**************算法功能实现开始**************/
	/********************************************/
	//如果底数 x 为负数并且指数 y 不是整数，将会导致 domain error 错误。
	//如果底数 x 和指数 y 都是 0，可能会导致 domain error 错误，也可能没有；这跟库的实现有关。
	//如果底数 x 是 0，指数 y 是负数，可能会导致 domain error 或 pole error 错误，也可能没有；这跟库的实现有关。
	//如果返回值 ret 太大或者太小，将会导致 range error 错误。
	if (bottom_value < 0 && fabs(index - (float)((int)index)) > PERMIT_ERROR)
		return false;
	else if (bottom_value == 0 && index == 0)
		Output_Value = k + bias;
	else if (bottom_value == 0 && index < 0)
		return false;
	else
		Output_Value = (float)(k * pow(bottom_value, index) + bias);
	/********************************************/
	/**************算法功能实现结束**************/
	/********************************************/

	/****************运算结果输出**************/
	AO[0] = Output_Value;
	/**************运算结果输出完毕************/
	return true;
#undef PERMIT_ERROR
}



//************************************
// Method:    	BCPARA						//< 广播SAMA参数变量函数（无参数需要广播的模块直接将BCPara函数设置为NULL即可）
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg			//< 模块参数结构体指针
// Parameter: 	void ** Data				//< 广播SAMA参数的数据包的指针
//************************************
int BC_PARA(POW)(Model_Base_t* arg, void** Data)
{
	NAME(POW)* Obj = (NAME(POW)*)arg;
	BC_PARA_PUBLIC(Obj);
	return 0;
}



//************************************
// Method:    	CHANGE_PAR				//< 在线修改模块参数函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int						//< 读取字节长度计数值
// Parameter: 	Model_Base_t* arg		//< 指定模块类型链表的指针
// Parameter: 	void** Data				//< 存放数据包当前指针位置的地址
//************************************
int CHANGE_PAR(POW)(Model_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD(((NAME(POW)*)arg)->Par, Data[0]);
	return _iLen;
}
